interface Person {
    name: string
    say(this: Person): void
}

const person: Person = {
    name: 'test',
    say() {
        console.log('name: ', this.name)
    }
}

person.say()
// TS2684: The 'this' context of type 'void' is 
// not assignable to method's 'this' of type 'Person'.
// const fn = person.say
// fn()

function test() {
    person.say()
    // 类型为“void”的 "this" 上下文不能分配给
    // 类型为“Person”的方法的 "this"。ts(2684)
    // const fn = person.say
    // fn()
}

class Container {
    private val: number
    constructor(val: number) {
        this.val = val
    }

    map(cb: (x: number) => number): this {
        this.val = cb(this.val)
        return this
    }

    log(): this {
        console.log('val is : ', this.val)
        return this
    }
}

new Container(1).map(x=>2*x+1).log().map(x=>x**x).log()


interface P1 {
    name: string;
}
interface P2 extends P1 {
    age: number;
}
function convert(x: P2): string;
function convert(x: P1): number;
function convert(x: P1 | P2): any {}

const x1 = convert({ name: "" } as P1); // => number
const x2 = convert({ name: "", age: 18 } as P2); // number